package com.nd.fastdp.org.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nd.fastdp.framework.exception.BusinessException;
import com.nd.fastdp.framework.pojo.constant.VerifyRespCodeEnum;
import com.nd.fastdp.framework.pojo.dto.DelParam;
import com.nd.fastdp.framework.pojo.dto.StateParam;
import com.nd.fastdp.org.convert.RoleConvert;
import com.nd.fastdp.org.convert.RoleDataScopeConvert;
import com.nd.fastdp.org.convert.RoleResourceConvert;
import com.nd.fastdp.org.dao.RoleDataScopeMapper;
import com.nd.fastdp.org.dao.RoleMapper;
import com.nd.fastdp.org.dao.RoleResourceMapper;
import com.nd.fastdp.org.model.bo.role.RoleBO;
import com.nd.fastdp.org.model.bo.role.RoleDataScopeBO;
import com.nd.fastdp.org.model.bo.role.RoleResourceBO;
import com.nd.fastdp.org.model.dto.role.*;
import com.nd.fastdp.org.model.entity.Role;
import com.nd.fastdp.org.model.entity.RoleDataScope;
import com.nd.fastdp.org.model.entity.RoleResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private RoleResourceMapper roleResourceMapper;

    @Autowired
    private RoleDataScopeMapper roleDataScopeMapper;

    @Override
    public RoleBO add(RoleAddParam param) {

        Role role = RoleConvert.INSTANCE.from(param);

        if(roleMapper.isExist(role.getName())){
            throw new BusinessException(VerifyRespCodeEnum.NAME_EXIST);
        }

        roleMapper.insert(role);

        return RoleConvert.INSTANCE.to(role);
    }

    @Override
    public void del(DelParam param) {
        roleMapper.del(param);
    }

    @Override
    public RoleBO modify(RoleModifyParam param) {

        Role role = RoleConvert.INSTANCE.from(param);

        if(roleMapper.isExist(role.getId(), role.getName())){
            throw new BusinessException(VerifyRespCodeEnum.NAME_EXIST);
        }

        roleMapper.updateById(role);

        return get(role.getId());
    }

    @Override
    public void modifyState(StateParam param) {
        roleMapper.updateState(param);
    }

    @Override
    public RoleBO get(String id) {

        Role dict = roleMapper.selectById(id);

        RoleBO roleBO = RoleConvert.INSTANCE.to(dict);

        fillDataScope(roleBO);

        return roleBO;
    }

    @Override
    public List<RoleBO> findByUserId(String userId) {

        List<Role> roles =  roleMapper.findByUserId(userId);

        List<RoleBO> roleBOS = RoleConvert.INSTANCE.to(roles);

        return roleBOS;
    }

    @Override
    public List<RoleBO> listAllEnable() {

        List<Role> roles =  roleMapper.listAllEnable();

        List<RoleBO> roleBOS = RoleConvert.INSTANCE.to(roles);

        return roleBOS;
    }

    @Override
    public List<RoleBO> listAll() {

        List<Role> roles =  roleMapper.listAll();

        List<RoleBO> roleBOS = RoleConvert.INSTANCE.to(roles);

        return roleBOS;
    }

    @Override
    public List<RoleBO> list(RoleListParam param) {

        List<Role> roles =  roleMapper.list(param);

        List<RoleBO> roleBOS = RoleConvert.INSTANCE.to(roles);

        return roleBOS;
    }

    @Override
    public Page<RoleBO> page(RoleQueryParam param) {

        IPage<Role> page =  roleMapper.page(param.getPage(), param);

        return RoleConvert.INSTANCE.to(page);
    }

    @Override
    @Transactional
    public void add(RoleResourceAddParam param) {

        roleResourceMapper.del(param.getRoleId());

        RoleResource roleResource = null;
        for (String resourceCode : param.getResourceCodes()){

            roleResource = new RoleResource();

            roleResource.setRoleId(param.getRoleId());
            roleResource.setResourceCode(resourceCode);

            roleResourceMapper.insert(roleResource);
        }

        roleDataScopeMapper.del(param.getRoleId());

        RoleDataScope dataScope = null;
        if(param.getDataScopeIds() != null){
            for (String dataScopeId : param.getDataScopeIds()){

                dataScope = new RoleDataScope();

                dataScope.setRoleId(param.getRoleId());
                dataScope.setDataScopeId(dataScopeId);

                roleDataScopeMapper.insert(dataScope);
            }
        }

    }

    @Override
    public List<RoleResourceBO> findRoleResourcesByRoleId(String roleId) {

        List<RoleResource> roleResources = roleResourceMapper.findRoleResourcesByRoleId(roleId);

        return RoleResourceConvert.INSTANCE.to(roleResources);
    }

    private void fillDataScope(List<RoleBO> roleBOs){

        for (RoleBO roleBO : roleBOs){
            fillDataScope(roleBO);
        }
    }

    private void fillDataScope(RoleBO roleBO){

        List<RoleDataScope> dataScopes = roleDataScopeMapper.findByRoleId(roleBO.getId());

        List<RoleDataScopeBO> roleDataScopeBOS = RoleDataScopeConvert.INSTANCE.to(dataScopes);

        roleBO.setDataScopes(roleDataScopeBOS);
    }
}
